library(tidyverse) # for data import, manipulation, viz
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ─────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  2.1.3     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
load("~/Documents/GitHub/Berkeley_DS/w203_stats/w203_project3/lab_3-master/data_clean.rda")
filter <- dplyr::filter
library(car)
Loading required package: carData
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: ‘car’

The following object is masked from ‘package:dplyr’:

    recode

The following object is masked from ‘package:purrr’:

    some
library(lmtest)
Loading required package: zoo

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric
library(stargazer)

Please cite as: 

 Hlavac, Marek (2018). stargazer: Well-Formatted Regression and Summary Statistics Tables.
 R package version 5.2.2. https://CRAN.R-project.org/package=stargazer 
library(sandwich)

crime_df = data2

EDA

Dependent Variable: Crime Rate

str(crime_df$crmrte)
 num [1:90] 0.0356 0.0153 0.013 0.0268 0.0106 ...
summary(crime_df %>% select(crmrte))
     crmrte        
 Min.   :0.005533  
 1st Qu.:0.020604  
 Median :0.030002  
 Mean   :0.033510  
 3rd Qu.:0.040249  
 Max.   :0.098966  
ggplot(crime_df, aes(x=crmrte)) +
  geom_histogram(bins = 20)

This variable follows a quasi-normal distribution with a slight skew to the left.

qqnorm(crime_df$crmrte)
qqline(crime_df$crmrte)

The Q-Q plot shows that the crmrte variable is not normal. There is heavy positive skewness.

Independent Variables: Criminal Justice System

crime_df = crime_df %>%  mutate(pris_crime_rt = prbarr * prbconv * prbpris)

justice_sys_df =  crime_df %>% 
  select(crmrte, prbarr, prbconv, prbpris, avgsen, pris_crime_rt)
print("Summary Statistics of Criminal Justice System Variables")
[1] "Summary Statistics of Criminal Justice System Variables"
summary(justice_sys_df)
     crmrte             prbarr           prbconv           prbpris           avgsen       pris_crime_rt    
 Min.   :0.005533   Min.   :0.09277   Min.   :0.06838   Min.   :0.1500   Min.   : 5.380   Min.   :0.01064  
 1st Qu.:0.020604   1st Qu.:0.20495   1st Qu.:0.34422   1st Qu.:0.3642   1st Qu.: 7.375   1st Qu.:0.03452  
 Median :0.030002   Median :0.27146   Median :0.45170   Median :0.4222   Median : 9.110   Median :0.05267  
 Mean   :0.033510   Mean   :0.29524   Mean   :0.55086   Mean   :0.4106   Mean   : 9.689   Mean   :0.06668  
 3rd Qu.:0.040249   3rd Qu.:0.34487   3rd Qu.:0.58513   3rd Qu.:0.4576   3rd Qu.:11.465   3rd Qu.:0.07301  
 Max.   :0.098966   Max.   :1.09091   Max.   :2.12121   Max.   :0.6000   Max.   :20.700   Max.   :0.81818  

Probability of Arrest

paste("Number of Observations:", length(justice_sys_df$prbarr))
[1] "Number of Observations: 90"
ggplot(justice_sys_df, aes(x = prbarr)) +
  geom_histogram(bins = 30)

There seems to be some outliers after 0.6. There is one data point over the value of 1, which is the most suspicious.

qqnorm(justice_sys_df$prbarr)
qqline(justice_sys_df$prbarr)

The probability of arrest’s ditribution also approximates a normal distribution. Mostly positive skeewness and one outlier affects the normality of the variable’s sample distribution.

Probability of Conviction

paste("Number of Observations:", length(justice_sys_df$prbconv))
[1] "Number of Observations: 90"
ggplot(justice_sys_df, aes(x = prbconv)) +
  geom_histogram(bins = 10)

There seems to be some outliers around 2. There distribution is positively skewed.

qqnorm(prbconv_df$prbconv)
qqline(prbconv_df$prbconv)

The probability of conversion has some heavy positive skewness and some outliers to the right.

Probability of Prison Sentence

print(paste("Number of Observations:", length(justice_sys_df$prbpris)))
[1] "Number of Observations: 90"
ggplot(justice_sys_df, aes(x = prbpris)) +
  geom_histogram()

qqnorm(prbpris_df$prbpris)
qqline(prbpris_df$prbpris)

Average Sentence (days)

print(paste("Number of Observations:", length(justice_sys_df$avgsen)))
[1] "Number of Observations: 90"

We seem to have some outliers after 20. The distribution of the variable doesn’t seem very normal.

qqnorm(justice_sys_df$avgsen)
qqline(justice_sys_df$avgsen)

Fairly normally distributed but the aglomeration on the left side and some outliers on the right make the sample distribution less normal.

ggplot(justice_sys_df, aes(x = avgsen)) +
  geom_histogram(bins = 40)

Feature Engineering: Prision Sentence to Crime Ratio

ggplot(justice_sys_df, aes(x = prbarr * prbconv * prbpris)) +
  geom_histogram(bins = 50)

Corellation

Correlation matrix for potential objective variable.

cor(justice_sys_df, method = "spearman")  # using spearman's correlation because the variables don't follow a normal distribution
                    crmrte      prbarr     prbconv      prbpris      avgsen pris_crime_rt
crmrte         1.000000000 -0.35157427 -0.34660246  0.001218277  0.08015870    -0.5160719
prbarr        -0.351574268  1.00000000 -0.19942380  0.014890972 -0.08460373     0.3605630
prbconv       -0.346602461 -0.19942380  1.00000000  0.053546587 -0.01754964     0.7295633
prbpris        0.001218277  0.01489097  0.05354659  1.000000000 -0.17037915     0.3194439
avgsen         0.080158704 -0.08460373 -0.01754964 -0.170379151  1.00000000    -0.1335731
pris_crime_rt -0.516071943  0.36056303  0.72956332  0.319443873 -0.13357315     1.0000000

prbarr: Low correlation with prbconv and prbpris and avgsen. prbconv: Low correlation with prbprisand avgsen. prbpris: Low correlation with avgsen. avgsen: Low correlation with all. pris_crime_rt: High correlation with prbarr and prbconv and prbpris.

All the Criminal Justice System variables have low correlation with each other, which gives us confident that we can include them all in a model and that doing so will not increase the variance of our coefficients.

Bivariate Analysis

Crime Rate vs Probability of Arrest

ggplot(crime_df, aes(x=prbarr, y=crmrte)) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE) +
  ggtitle("Scatterplot of Crime Rate vs Probability of Arrest")

Clear negative relationship. The higher the Probability of Arrest, the lower the Crime Rate.

Crime Rate vs Probability of Conviction

ggplot(crime_df, aes(x=prbconv, y=crmrte)) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE)

Negative realtionship although there is some positive data skewness.

Crime Rate vs Probability of Prision

ggplot(crime_df, aes(x=prbpris, y=crmrte)) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE)

There is no strong correlation between Probability of Prision and Crime Rate. Test linear model with and without Probabiity of Prision.

Crime Rate vs Avegace Sentence (days)

ggplot(crime_df, aes(x=avgsen, y=crmrte)) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE)

There is no strong correlation between Probability of Prision and Crime Rate. Test linear model with and without avgsen.

ggplot(crime_df, aes(x= (prbarr* prbconv * prbpris),  y=crmrte)) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE)

Liner Models

justice_sys_1_md = lm(crmrte ~ prbarr + prbconv, data = justice_sys_data_df)
justice_sys_1_md$coefficients
(Intercept)      prbarr     prbconv 
 0.06246762 -0.05736077 -0.02182518 
plot(justice_sys_1_md)

Zero Conditional Mean: The residuals don’t seem to have a zero conditional mean. This is not a major issue because we have large sample size so we can invoke the CLT to have more confidence on the coefficients.

Normality of Errors: The residuals have a fairly normal distirbution with the exception of some positve skewness.

Heteroskadiscity: Complete violation.

Outliers: There is one observation with high leverage and influence.

Next Steps: In order to address the Zero Conditional Mean and Heteroskasdiscity issues, we will ;og-transform crmrte, prbarr, and prbconv. Those variables had a positively skewed distribution so a log transform could help. Note that all variables have values greater than zero so we can log-transform them without issues.

justice_sys_2_md = lm(log(crmrte) ~ log(prbarr) + log(prbconv), data = justice_sys_df)
justice_sys_2_md$coefficients
 (Intercept)  log(prbarr) log(prbconv) 
  -4.8450828   -0.7260022   -0.4716933 
plot(justice_sys_2_md)

Zero Conditional Mean: Although the residuals don’t seem to have a perfect zero conditional mean, the residuals have gotten much closer to zero conditional mean.

Normality of Errors: The residuals have a fairly normal distirbution with the exception of some positve skewness.

Heteroskadiscity: Complete violation. We would need to use standard errors with White’s adjustment to assess signficance of t-values.

Outliers: There is one observation with high leverage but not high influence.

Next Steps: Heteroskadiscity could be a sign of omitted variables. We will add the remainder

justice_sys_3_md = lm(log(crmrte) ~ log(prbarr) + log(prbconv) + prbpris + avgsen, data = justice_sys_df)
justice_sys_3_md$coefficients
 (Intercept)  log(prbarr) log(prbconv)      prbpris       avgsen 
-4.938924985 -0.727096099 -0.472492046  0.179215398  0.001880653 
plot(justice_sys_3_md)

Zero Conditional Mean: Although the residuals don’t seem to have a perfect zero conditional mean, the residuals have gotten much closer to zero conditional mean.

Normality of Errors: The residuals have a fairly normal distirbution with the exception of some positve skewness.

Heteroskadiscity: Complete violation. We would need to use standard errors with White’s adjustment to assess signficance of t-values.

Outliers: There is one observation with high leverage but not high influence.

Next Steps: There was no impact on adding the prbpris and avgsen. We will exclude those from the model for now.

justice_sys_4_md = lm(log(crmrte) ~ log(pris_crime_rt), data = justice_sys_df)
justice_sys_4_md$coefficients
       (Intercept) log(pris_crime_rt) 
        -4.9372291         -0.4695287 
plot(justice_sys_4_md)

Zero Conditional Mean: Although the residuals don’t seem to have a perfect zero conditional mean, the residuals have gotten much closer to zero conditional mean.

Normality of Errors: The residuals have a fairly normal distirbution with the exception of some positve skewness.

Heteroskadiscity: Complete violation. We would need to use standard errors with White’s adjustment to assess signficance of t-values.

Outliers: There is one observation with high leverage but not high influence.

Law Enforcement

Police per Capita

justice_police_df =  crime_df %>% select(crmrte, prbarr, prbconv, prbpris, avgsen, polpc, pris_crime_rt)
summary(justice_police_df)
     crmrte             prbarr           prbconv           prbpris           avgsen           polpc           pris_crime_rt    
 Min.   :0.005533   Min.   :0.09277   Min.   :0.06838   Min.   :0.1500   Min.   : 5.380   Min.   :0.0007459   Min.   :0.01064  
 1st Qu.:0.020604   1st Qu.:0.20495   1st Qu.:0.34422   1st Qu.:0.3642   1st Qu.: 7.375   1st Qu.:0.0012378   1st Qu.:0.03452  
 Median :0.030002   Median :0.27146   Median :0.45170   Median :0.4222   Median : 9.110   Median :0.0014897   Median :0.05267  
 Mean   :0.033510   Mean   :0.29524   Mean   :0.55086   Mean   :0.4106   Mean   : 9.689   Mean   :0.0017080   Mean   :0.06668  
 3rd Qu.:0.040249   3rd Qu.:0.34487   3rd Qu.:0.58513   3rd Qu.:0.4576   3rd Qu.:11.465   3rd Qu.:0.0018856   3rd Qu.:0.07301  
 Max.   :0.098966   Max.   :1.09091   Max.   :2.12121   Max.   :0.6000   Max.   :20.700   Max.   :0.0090543   Max.   :0.81818  
ggplot(justice_police_df, aes(x = polpc)) +
  geom_histogram()

qqnorm(justice_police_data_df$polpc)
qqline(justice_police_data_df$polpc)

Strong positive skewness and outlier.

Correlation

cor(justice_police_df, method = "spearman")
                    crmrte      prbarr     prbconv       prbpris      avgsen         polpc pris_crime_rt
crmrte         1.000000000 -0.35157427 -0.34660246  0.0012182775  0.08015870  0.5258015393    -0.5160719
prbarr        -0.351574268  1.00000000 -0.19942380  0.0148909724 -0.08460373 -0.1598304317     0.3605630
prbconv       -0.346602461 -0.19942380  1.00000000  0.0535465868 -0.01754964 -0.3134131786     0.7295633
prbpris        0.001218277  0.01489097  0.05354659  1.0000000000 -0.17037915 -0.0005762123     0.3194439
avgsen         0.080158704 -0.08460373 -0.01754964 -0.1703791508  1.00000000  0.2648990814    -0.1335731
polpc          0.525801539 -0.15983043 -0.31341318 -0.0005762123  0.26489908  1.0000000000    -0.4090793
pris_crime_rt -0.516071943  0.36056303  0.72956332  0.3194438728 -0.13357315 -0.4090793102     1.0000000

polpc: medium positive correlation with prbconv and avgsen and pris_crime_rt.

Note that polpc has high correlation with pris_crime_rt so it could impact the efficiency of our coefficient estimation if both variables are included in the model.

Bivariate Analysis

Crime Rate vs Police per Capita

We log-transform the polpc variable because we had noticed that doing so for positively-skewed variable reduced residuals.

ggplot(crime_df, aes(x=log(polpc), y=log(crmrte))) + 
  geom_point()+
  geom_smooth(method=lm, se=FALSE)

Linear Models

justice_police_md = lm(log(crmrte) ~ log(prbarr) + log(prbconv) + log(polpc), data = justice_police_df)
justice_police_md$coefficients
 (Intercept)  log(prbarr) log(prbconv)   log(polpc) 
  -2.4471800   -0.7353714   -0.4387689    0.3693199 
plot(justice_police_md)

Zero Conditional Mean: No noticible improvement compared to \(crimeRate = \beta_0 + \beta_1 * prisCrimeRt + \hat{u}\)

Normality of Errors: The residuals have a fairly normal distirbution with the exception of some positve skewness.

Heteroskadiscity: Although the residuals are still not heteroskadistic, there has been some improvement.

Outliers: There is one observation with high leverage but not high influence.

Next Steps: Heteroskadiscity could be a sign of omitted variables.

m2 <- lm(log(crmrte) ~ log(eff_cj), data = data2);
LS0tCnRpdGxlOiAibGFiXzNfMSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKSAjIGZvciBkYXRhIGltcG9ydCwgbWFuaXB1bGF0aW9uLCB2aXoKbG9hZCgifi9Eb2N1bWVudHMvR2l0SHViL0JlcmtlbGV5X0RTL3cyMDNfc3RhdHMvdzIwM19wcm9qZWN0My9sYWJfMy1tYXN0ZXIvZGF0YV9jbGVhbi5yZGEiKQpmaWx0ZXIgPC0gZHBseXI6OmZpbHRlcgpsaWJyYXJ5KGNhcikKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc3RhcmdhemVyKQpsaWJyYXJ5KHNhbmR3aWNoKQoKY3JpbWVfZGYgPSBkYXRhMgpgYGAKCiMgRURBCgojIyBEZXBlbmRlbnQgVmFyaWFibGU6IENyaW1lIFJhdGUKCmBgYHtyfQpzdHIoY3JpbWVfZGYkY3JtcnRlKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGNyaW1lX2RmICU+JSBzZWxlY3QoY3JtcnRlKSkKYGBgYAoKCmBgYHtyfQpnZ3Bsb3QoY3JpbWVfZGYsIGFlcyh4PWNybXJ0ZSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMjApCmBgYAoKVGhpcyB2YXJpYWJsZSBmb2xsb3dzIGEgcXVhc2ktbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIGEgc2xpZ2h0IHNrZXcgdG8gdGhlIGxlZnQuCgpgYGB7cn0KcXFub3JtKGNyaW1lX2RmJGNybXJ0ZSkKcXFsaW5lKGNyaW1lX2RmJGNybXJ0ZSkKYGBgCgpUaGUgUS1RIHBsb3Qgc2hvd3MgdGhhdCB0aGUgYGNybXJ0ZWAgdmFyaWFibGUgaXMgbm90IG5vcm1hbC4gVGhlcmUgaXMgaGVhdnkgcG9zaXRpdmUgc2tld25lc3MuCgojIyBJbmRlcGVuZGVudCBWYXJpYWJsZXM6IENyaW1pbmFsIEp1c3RpY2UgU3lzdGVtIAoKYGBge3J9CmNyaW1lX2RmID0gY3JpbWVfZGYgJT4lICBtdXRhdGUocHJpc19jcmltZV9ydCA9IHByYmFyciAqIHByYmNvbnYgKiBwcmJwcmlzKQoKanVzdGljZV9zeXNfZGYgPSAgY3JpbWVfZGYgJT4lIAogIHNlbGVjdChjcm1ydGUsIHByYmFyciwgcHJiY29udiwgcHJicHJpcywgYXZnc2VuLCBwcmlzX2NyaW1lX3J0KQpwcmludCgiU3VtbWFyeSBTdGF0aXN0aWNzIG9mIENyaW1pbmFsIEp1c3RpY2UgU3lzdGVtIFZhcmlhYmxlcyIpCnN1bW1hcnkoanVzdGljZV9zeXNfZGYpCmBgYAoKIyMjIFByb2JhYmlsaXR5IG9mIEFycmVzdAoKYGBge3J9CnBhc3RlKCJOdW1iZXIgb2YgT2JzZXJ2YXRpb25zOiIsIGxlbmd0aChqdXN0aWNlX3N5c19kZiRwcmJhcnIpKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoanVzdGljZV9zeXNfZGYsIGFlcyh4ID0gcHJiYXJyKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAzMCkKYGBgCgpUaGVyZSBzZWVtcyB0byBiZSBzb21lIG91dGxpZXJzIGFmdGVyIDAuNi4gVGhlcmUgaXMgb25lIGRhdGEgcG9pbnQgb3ZlciB0aGUgdmFsdWUgb2YgMSwgd2hpY2ggaXMgdGhlIG1vc3Qgc3VzcGljaW91cy4KCmBgYHtyfQpxcW5vcm0oanVzdGljZV9zeXNfZGYkcHJiYXJyKQpxcWxpbmUoanVzdGljZV9zeXNfZGYkcHJiYXJyKQpgYGAKClRoZSBwcm9iYWJpbGl0eSBvZiBhcnJlc3QncyBkaXRyaWJ1dGlvbiBhbHNvIGFwcHJveGltYXRlcyBhIG5vcm1hbCBkaXN0cmlidXRpb24uIE1vc3RseSBwb3NpdGl2ZSBza2Vld25lc3MgYW5kIG9uZSBvdXRsaWVyIGFmZmVjdHMgdGhlIG5vcm1hbGl0eSBvZiB0aGUgdmFyaWFibGUncyBzYW1wbGUgZGlzdHJpYnV0aW9uLgoKIyMjIFByb2JhYmlsaXR5IG9mIENvbnZpY3Rpb24KCmBgYHtyfQpwYXN0ZSgiTnVtYmVyIG9mIE9ic2VydmF0aW9uczoiLCBsZW5ndGgoanVzdGljZV9zeXNfZGYkcHJiY29udikpCmBgYAoKYGBge3J9CmdncGxvdChqdXN0aWNlX3N5c19kZiwgYWVzKHggPSBwcmJjb252KSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAxMCkKYGBgCgpUaGVyZSBzZWVtcyB0byBiZSBzb21lIG91dGxpZXJzIGFyb3VuZCAyLiBUaGVyZSBkaXN0cmlidXRpb24gaXMgcG9zaXRpdmVseSBza2V3ZWQuCgpgYGB7cn0KcXFub3JtKHByYmNvbnZfZGYkcHJiY29udikKcXFsaW5lKHByYmNvbnZfZGYkcHJiY29udikKYGBgCgpUaGUgcHJvYmFiaWxpdHkgb2YgY29udmVyc2lvbiBoYXMgc29tZSBoZWF2eSBwb3NpdGl2ZSBza2V3bmVzcyBhbmQgc29tZSBvdXRsaWVycyB0byB0aGUgcmlnaHQuCgojIyMgUHJvYmFiaWxpdHkgb2YgUHJpc29uIFNlbnRlbmNlCgpgYGB7cn0KcHJpbnQocGFzdGUoIk51bWJlciBvZiBPYnNlcnZhdGlvbnM6IiwgbGVuZ3RoKGp1c3RpY2Vfc3lzX2RmJHByYnByaXMpKSkKYGBgCgpgYGB7cn0KZ2dwbG90KGp1c3RpY2Vfc3lzX2RmLCBhZXMoeCA9IHByYnByaXMpKSArCiAgZ2VvbV9oaXN0b2dyYW0oKQpgYGAKCmBgYHtyfQpxcW5vcm0ocHJicHJpc19kZiRwcmJwcmlzKQpxcWxpbmUocHJicHJpc19kZiRwcmJwcmlzKQpgYGAKCgojIyMgQXZlcmFnZSBTZW50ZW5jZSAoZGF5cykKCmBgYHtyfQpwcmludChwYXN0ZSgiTnVtYmVyIG9mIE9ic2VydmF0aW9uczoiLCBsZW5ndGgoanVzdGljZV9zeXNfZGYkYXZnc2VuKSkpCmBgYAoKV2Ugc2VlbSB0byBoYXZlIHNvbWUgb3V0bGllcnMgYWZ0ZXIgMjAuIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHZhcmlhYmxlIGRvZXNuJ3Qgc2VlbSB2ZXJ5IG5vcm1hbC4KCgpgYGB7cn0KcXFub3JtKGp1c3RpY2Vfc3lzX2RmJGF2Z3NlbikKcXFsaW5lKGp1c3RpY2Vfc3lzX2RmJGF2Z3NlbikKYGBgCgpGYWlybHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYnV0IHRoZSBhZ2xvbWVyYXRpb24gb24gdGhlIGxlZnQgc2lkZSBhbmQgc29tZSBvdXRsaWVycyBvbiB0aGUgcmlnaHQgbWFrZSB0aGUgc2FtcGxlIGRpc3RyaWJ1dGlvbiBsZXNzIG5vcm1hbC4KCmBgYHtyfQpnZ3Bsb3QoanVzdGljZV9zeXNfZGYsIGFlcyh4ID0gYXZnc2VuKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSA0MCkKYGBgCgojIyMgRmVhdHVyZSBFbmdpbmVlcmluZzogUHJpc2lvbiBTZW50ZW5jZSB0byBDcmltZSBSYXRpbwpgYGB7cn0KZ2dwbG90KGp1c3RpY2Vfc3lzX2RmLCBhZXMoeCA9IHByYmFyciAqIHByYmNvbnYgKiBwcmJwcmlzKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSA1MCkKYGBgCgoKIyMjIENvcmVsbGF0aW9uCgpDb3JyZWxhdGlvbiBtYXRyaXggZm9yIHBvdGVudGlhbCBvYmplY3RpdmUgdmFyaWFibGUuCgpgYGB7cn0KY29yKGp1c3RpY2Vfc3lzX2RmLCBtZXRob2QgPSAic3BlYXJtYW4iKSAgIyB1c2luZyBzcGVhcm1hbidzIGNvcnJlbGF0aW9uIGJlY2F1c2UgdGhlIHZhcmlhYmxlcyBkb24ndCBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uCmBgYAoKcHJiYXJyOiBMb3cgY29ycmVsYXRpb24gd2l0aCBgcHJiY29udmAgYW5kIGBwcmJwcmlzYCBhbmQgYGF2Z3NlbmAuCnByYmNvbnY6IExvdyBjb3JyZWxhdGlvbiB3aXRoIGBwcmJwcmlzYGFuZCBgYXZnc2VuYC4KcHJicHJpczogTG93IGNvcnJlbGF0aW9uIHdpdGggYGF2Z3NlbmAuCmF2Z3NlbjogTG93IGNvcnJlbGF0aW9uIHdpdGggYWxsLgpwcmlzX2NyaW1lX3J0OiBIaWdoIGNvcnJlbGF0aW9uIHdpdGggYHByYmFycmAgYW5kIGBwcmJjb252YCBhbmQgYHByYnByaXNgLgoKQWxsIHRoZSBDcmltaW5hbCBKdXN0aWNlIFN5c3RlbSB2YXJpYWJsZXMgaGF2ZSBsb3cgY29ycmVsYXRpb24gd2l0aCBlYWNoIG90aGVyLCB3aGljaCBnaXZlcyB1cyBjb25maWRlbnQgdGhhdCB3ZSBjYW4gaW5jbHVkZSB0aGVtIGFsbCBpbiBhIG1vZGVsIGFuZCB0aGF0IGRvaW5nIHNvIHdpbGwgbm90IGluY3JlYXNlIHRoZSB2YXJpYW5jZSBvZiBvdXIgY29lZmZpY2llbnRzLiAKCiMjIyBCaXZhcmlhdGUgQW5hbHlzaXMKCiMjIyMgQ3JpbWUgUmF0ZSB2cyBQcm9iYWJpbGl0eSBvZiBBcnJlc3QKCmBgYHtyfQpnZ3Bsb3QoY3JpbWVfZGYsIGFlcyh4PXByYmFyciwgeT1jcm1ydGUpKSArIAogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKSArCiAgZ2d0aXRsZSgiU2NhdHRlcnBsb3Qgb2YgQ3JpbWUgUmF0ZSB2cyBQcm9iYWJpbGl0eSBvZiBBcnJlc3QiKQpgYGAKCkNsZWFyIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcC4gVGhlIGhpZ2hlciB0aGUgUHJvYmFiaWxpdHkgb2YgQXJyZXN0LCB0aGUgbG93ZXIgdGhlIENyaW1lIFJhdGUuCgojIyMjIENyaW1lIFJhdGUgdnMgUHJvYmFiaWxpdHkgb2YgQ29udmljdGlvbgoKYGBge3J9CmdncGxvdChjcmltZV9kZiwgYWVzKHg9cHJiY29udiwgeT1jcm1ydGUpKSArIAogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQpgYGAKCgpgYGB7cn0KZ2dwbG90KGNyaW1lX2RmLCBhZXMoeD1sb2cocHJiY29udiksIHk9Y3JtcnRlKSkgKyAKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1GQUxTRSkKYGBgCgoKYGBge3J9CmdncGxvdChjcmltZV9kZiwgYWVzKHg9bG9nKHByYmNvbnYpLCB5PWxvZyhjcm1ydGUpKSkgKyAKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1GQUxTRSkKYGBgCgoKCk5lZ2F0aXZlIHJlYWx0aW9uc2hpcCBhbHRob3VnaCB0aGVyZSBpcyBzb21lIHBvc2l0aXZlIGRhdGEgc2tld25lc3MuCgojIyMjIENyaW1lIFJhdGUgdnMgUHJvYmFiaWxpdHkgb2YgUHJpc2lvbgoKYGBge3J9CmdncGxvdChjcmltZV9kZiwgYWVzKHg9cHJicHJpcywgeT1jcm1ydGUpKSArIAogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQpgYGAKClRoZXJlIGlzIG5vIHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIFByb2JhYmlsaXR5IG9mIFByaXNpb24gYW5kIENyaW1lIFJhdGUuIFRlc3QgbGluZWFyIG1vZGVsIHdpdGggYW5kIHdpdGhvdXQgUHJvYmFiaWl0eSBvZiBQcmlzaW9uLgoKIyMjIyBDcmltZSBSYXRlIHZzIEF2ZWdhY2UgU2VudGVuY2UgKGRheXMpCgpgYGB7cn0KZ2dwbG90KGNyaW1lX2RmLCBhZXMoeD1hdmdzZW4sIHk9Y3JtcnRlKSkgKyAKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1GQUxTRSkKYGBgCgpUaGVyZSBpcyBubyBzdHJvbmcgY29ycmVsYXRpb24gYmV0d2VlbiBQcm9iYWJpbGl0eSBvZiBQcmlzaW9uIGFuZCBDcmltZSBSYXRlLiBUZXN0IGxpbmVhciBtb2RlbCB3aXRoIGFuZCB3aXRob3V0IGF2Z3Nlbi4KCgpgYGB7cn0KZ2dwbG90KGNyaW1lX2RmLCBhZXMoeD0gKHByYmFyciogcHJiY29udiAqIHByYnByaXMpLCAgeT1jcm1ydGUpKSArIAogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQpgYGAKCiMjIyBMaW5lciBNb2RlbHMKCmBgYHtyfQpqdXN0aWNlX3N5c18xX21kID0gbG0oY3JtcnRlIH4gcHJiYXJyICsgcHJiY29udiwgZGF0YSA9IGp1c3RpY2Vfc3lzX2RhdGFfZGYpCmp1c3RpY2Vfc3lzXzFfbWQkY29lZmZpY2llbnRzCmBgYAoKYGBge3J9CnBsb3QoanVzdGljZV9zeXNfMV9tZCkKYGBgCgoqKlplcm8gQ29uZGl0aW9uYWwgTWVhbjoqKiBUaGUgcmVzaWR1YWxzIGRvbid0IHNlZW0gdG8gaGF2ZSBhIHplcm8gY29uZGl0aW9uYWwgbWVhbi4gVGhpcyBpcyBub3QgYSBtYWpvciBpc3N1ZSBiZWNhdXNlIHdlIGhhdmUgbGFyZ2Ugc2FtcGxlIHNpemUgc28gd2UgY2FuIGludm9rZSB0aGUgQ0xUIHRvIGhhdmUgbW9yZSBjb25maWRlbmNlIG9uIHRoZSBjb2VmZmljaWVudHMuCgoqKk5vcm1hbGl0eSBvZiBFcnJvcnM6KiogVGhlIHJlc2lkdWFscyBoYXZlIGEgZmFpcmx5IG5vcm1hbCBkaXN0aXJidXRpb24gd2l0aCB0aGUgZXhjZXB0aW9uIG9mIHNvbWUgcG9zaXR2ZSBza2V3bmVzcy4KCioqSGV0ZXJvc2thZGlzY2l0eSoqOiBDb21wbGV0ZSB2aW9sYXRpb24uCgoqKk91dGxpZXJzOioqIFRoZXJlIGlzIG9uZSBvYnNlcnZhdGlvbiB3aXRoIGhpZ2ggbGV2ZXJhZ2UgYW5kIGluZmx1ZW5jZS4KCk5leHQgU3RlcHM6IEluIG9yZGVyIHRvIGFkZHJlc3MgdGhlIFplcm8gQ29uZGl0aW9uYWwgTWVhbiBhbmQgSGV0ZXJvc2thc2Rpc2NpdHkgaXNzdWVzLCB3ZSB3aWxsIDtvZy10cmFuc2Zvcm0gY3JtcnRlLCBwcmJhcnIsIGFuZCBwcmJjb252LiBUaG9zZSB2YXJpYWJsZXMgaGFkIGEgcG9zaXRpdmVseSBza2V3ZWQgZGlzdHJpYnV0aW9uIHNvIGEgbG9nIHRyYW5zZm9ybSBjb3VsZCBoZWxwLiBOb3RlIHRoYXQgYWxsIHZhcmlhYmxlcyBoYXZlIHZhbHVlcyBncmVhdGVyIHRoYW4gemVybyBzbyB3ZSBjYW4gbG9nLXRyYW5zZm9ybSB0aGVtIHdpdGhvdXQgaXNzdWVzLgoKCmBgYHtyfQpqdXN0aWNlX3N5c18yX21kID0gbG0obG9nKGNybXJ0ZSkgfiBsb2cocHJiYXJyKSArIGxvZyhwcmJjb252KSwgZGF0YSA9IGp1c3RpY2Vfc3lzX2RmKQpqdXN0aWNlX3N5c18yX21kJGNvZWZmaWNpZW50cwpgYGAKCmBgYHtyfQpwbG90KGp1c3RpY2Vfc3lzXzJfbWQpCmBgYAoKKipaZXJvIENvbmRpdGlvbmFsIE1lYW46KiogQWx0aG91Z2ggdGhlIHJlc2lkdWFscyBkb24ndCBzZWVtIHRvIGhhdmUgYSBwZXJmZWN0IHplcm8gY29uZGl0aW9uYWwgbWVhbiwgdGhlIHJlc2lkdWFscyBoYXZlIGdvdHRlbiBtdWNoIGNsb3NlciB0byB6ZXJvIGNvbmRpdGlvbmFsIG1lYW4uCgoqKk5vcm1hbGl0eSBvZiBFcnJvcnM6KiogVGhlIHJlc2lkdWFscyBoYXZlIGEgZmFpcmx5IG5vcm1hbCBkaXN0aXJidXRpb24gd2l0aCB0aGUgZXhjZXB0aW9uIG9mIHNvbWUgcG9zaXR2ZSBza2V3bmVzcy4KCioqSGV0ZXJvc2thZGlzY2l0eSoqOiBDb21wbGV0ZSB2aW9sYXRpb24uIFdlIHdvdWxkIG5lZWQgdG8gdXNlIHN0YW5kYXJkIGVycm9ycyB3aXRoIFdoaXRlJ3MgYWRqdXN0bWVudCB0byBhc3Nlc3Mgc2lnbmZpY2FuY2Ugb2YgdC12YWx1ZXMuCgoqKk91dGxpZXJzOioqIFRoZXJlIGlzIG9uZSBvYnNlcnZhdGlvbiB3aXRoIGhpZ2ggbGV2ZXJhZ2UgYnV0IG5vdCBoaWdoIGluZmx1ZW5jZS4KCk5leHQgU3RlcHM6IEhldGVyb3NrYWRpc2NpdHkgY291bGQgYmUgYSBzaWduIG9mIG9taXR0ZWQgdmFyaWFibGVzLiBXZSB3aWxsIGFkZCB0aGUgcmVtYWluZGVyIAoKYGBge3J9Cmp1c3RpY2Vfc3lzXzNfbWQgPSBsbShsb2coY3JtcnRlKSB+IGxvZyhwcmJhcnIpICsgbG9nKHByYmNvbnYpICsgcHJicHJpcyArIGF2Z3NlbiwgZGF0YSA9IGp1c3RpY2Vfc3lzX2RmKQpqdXN0aWNlX3N5c18zX21kJGNvZWZmaWNpZW50cwpgYGAKYGBge3J9CnBsb3QoanVzdGljZV9zeXNfM19tZCkKYGBgCgoqKlplcm8gQ29uZGl0aW9uYWwgTWVhbjoqKiBBbHRob3VnaCB0aGUgcmVzaWR1YWxzIGRvbid0IHNlZW0gdG8gaGF2ZSBhIHBlcmZlY3QgemVybyBjb25kaXRpb25hbCBtZWFuLCB0aGUgcmVzaWR1YWxzIGhhdmUgZ290dGVuIG11Y2ggY2xvc2VyIHRvIHplcm8gY29uZGl0aW9uYWwgbWVhbi4KCioqTm9ybWFsaXR5IG9mIEVycm9yczoqKiBUaGUgcmVzaWR1YWxzIGhhdmUgYSBmYWlybHkgbm9ybWFsIGRpc3RpcmJ1dGlvbiB3aXRoIHRoZSBleGNlcHRpb24gb2Ygc29tZSBwb3NpdHZlIHNrZXduZXNzLgoKKipIZXRlcm9za2FkaXNjaXR5Kio6IENvbXBsZXRlIHZpb2xhdGlvbi4gV2Ugd291bGQgbmVlZCB0byB1c2Ugc3RhbmRhcmQgZXJyb3JzIHdpdGggV2hpdGUncyBhZGp1c3RtZW50IHRvIGFzc2VzcyBzaWduZmljYW5jZSBvZiB0LXZhbHVlcy4KCioqT3V0bGllcnM6KiogVGhlcmUgaXMgb25lIG9ic2VydmF0aW9uIHdpdGggaGlnaCBsZXZlcmFnZSBidXQgbm90IGhpZ2ggaW5mbHVlbmNlLgoKTmV4dCBTdGVwczogVGhlcmUgd2FzIG5vIGltcGFjdCBvbiBhZGRpbmcgdGhlIGBwcmJwcmlzYCBhbmQgYGF2Z3NlbmAuIFdlIHdpbGwgZXhjbHVkZSB0aG9zZSBmcm9tIHRoZSBtb2RlbCBmb3Igbm93LgoKYGBge3J9Cmp1c3RpY2Vfc3lzXzRfbWQgPSBsbShsb2coY3JtcnRlKSB+IGxvZyhwcmlzX2NyaW1lX3J0KSwgZGF0YSA9IGp1c3RpY2Vfc3lzX2RmKQpqdXN0aWNlX3N5c180X21kJGNvZWZmaWNpZW50cwpgYGAKCmBgYHtyfQpwbG90KGp1c3RpY2Vfc3lzXzRfbWQpCmBgYAoKKipaZXJvIENvbmRpdGlvbmFsIE1lYW46KiogQWx0aG91Z2ggdGhlIHJlc2lkdWFscyBkb24ndCBzZWVtIHRvIGhhdmUgYSBwZXJmZWN0IHplcm8gY29uZGl0aW9uYWwgbWVhbiwgdGhlIHJlc2lkdWFscyBoYXZlIGdvdHRlbiBtdWNoIGNsb3NlciB0byB6ZXJvIGNvbmRpdGlvbmFsIG1lYW4uCgoqKk5vcm1hbGl0eSBvZiBFcnJvcnM6KiogVGhlIHJlc2lkdWFscyBoYXZlIGEgZmFpcmx5IG5vcm1hbCBkaXN0aXJidXRpb24gd2l0aCB0aGUgZXhjZXB0aW9uIG9mIHNvbWUgcG9zaXR2ZSBza2V3bmVzcy4KCioqSGV0ZXJvc2thZGlzY2l0eSoqOiBDb21wbGV0ZSB2aW9sYXRpb24uIFdlIHdvdWxkIG5lZWQgdG8gdXNlIHN0YW5kYXJkIGVycm9ycyB3aXRoIFdoaXRlJ3MgYWRqdXN0bWVudCB0byBhc3Nlc3Mgc2lnbmZpY2FuY2Ugb2YgdC12YWx1ZXMuCgoqKk91dGxpZXJzOioqIFRoZXJlIGlzIG9uZSBvYnNlcnZhdGlvbiB3aXRoIGhpZ2ggbGV2ZXJhZ2UgYnV0IG5vdCBoaWdoIGluZmx1ZW5jZS4KCiMjIExhdyBFbmZvcmNlbWVudAoKCiMjIyBQb2xpY2UgcGVyIENhcGl0YQoKYGBge3J9Cmp1c3RpY2VfcG9saWNlX2RmID0gIGNyaW1lX2RmICU+JSBzZWxlY3QoY3JtcnRlLCBwcmJhcnIsIHByYmNvbnYsIHByYnByaXMsIGF2Z3NlbiwgcG9scGMsIHByaXNfY3JpbWVfcnQpCnN1bW1hcnkoanVzdGljZV9wb2xpY2VfZGYpCmBgYAoKYGBge3J9CmdncGxvdChqdXN0aWNlX3BvbGljZV9kZiwgYWVzKHggPSBwb2xwYykpICsKICBnZW9tX2hpc3RvZ3JhbSgpCmBgYAoKCmBgYHtyfQpxcW5vcm0oanVzdGljZV9wb2xpY2VfZGF0YV9kZiRwb2xwYykKcXFsaW5lKGp1c3RpY2VfcG9saWNlX2RhdGFfZGYkcG9scGMpCmBgYAoKU3Ryb25nIHBvc2l0aXZlIHNrZXduZXNzIGFuZCBvdXRsaWVyLgoKCiMjIyBDb3JyZWxhdGlvbgoKYGBge3J9CmNvcihqdXN0aWNlX3BvbGljZV9kZiwgbWV0aG9kID0gInNwZWFybWFuIikKYGBgCgpwb2xwYzogbWVkaXVtIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdpdGggYHByYmNvbnZgIGFuZCBgYXZnc2VuYCBhbmQgYHByaXNfY3JpbWVfcnRgLgoKTm90ZSB0aGF0IGBwb2xwY2AgaGFzIGhpZ2ggY29ycmVsYXRpb24gd2l0aCBgcHJpc19jcmltZV9ydGAgc28gaXQgY291bGQgaW1wYWN0IHRoZSBlZmZpY2llbmN5IG9mIG91ciBjb2VmZmljaWVudCBlc3RpbWF0aW9uIGlmIGJvdGggdmFyaWFibGVzIGFyZSBpbmNsdWRlZCBpbiB0aGUgbW9kZWwuCgojIyMgQml2YXJpYXRlIEFuYWx5c2lzCgojIyMjIENyaW1lIFJhdGUgdnMgUG9saWNlIHBlciBDYXBpdGEKCldlIGxvZy10cmFuc2Zvcm0gdGhlIGBwb2xwY2AgdmFyaWFibGUgYmVjYXVzZSB3ZSBoYWQgbm90aWNlZCB0aGF0IGRvaW5nIHNvIGZvciBwb3NpdGl2ZWx5LXNrZXdlZCB2YXJpYWJsZSByZWR1Y2VkIHJlc2lkdWFscy4KCmBgYHtyfQpnZ3Bsb3QoY3JpbWVfZGYsIGFlcyh4PWxvZyhwb2xwYyksIHk9bG9nKGNybXJ0ZSkpKSArIAogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQpgYGAKCiMjIyBMaW5lYXIgTW9kZWxzCgpgYGB7cn0KanVzdGljZV9wb2xpY2VfbWQgPSBsbShsb2coY3JtcnRlKSB+IGxvZyhwcmJhcnIpICsgbG9nKHByYmNvbnYpICsgbG9nKHBvbHBjKSwgZGF0YSA9IGp1c3RpY2VfcG9saWNlX2RmKQpqdXN0aWNlX3BvbGljZV9tZCRjb2VmZmljaWVudHMKYGBgCgoKYGBge3J9CnBsb3QoanVzdGljZV9wb2xpY2VfbWQpCmBgYAoKKipaZXJvIENvbmRpdGlvbmFsIE1lYW46KiogTm8gbm90aWNpYmxlIGltcHJvdmVtZW50IGNvbXBhcmVkIHRvICRjcmltZVJhdGUgPSBcYmV0YV8wICsgXGJldGFfMSAqIHByaXNDcmltZVJ0ICsgXGhhdHt1fSQKCioqTm9ybWFsaXR5IG9mIEVycm9yczoqKiBUaGUgcmVzaWR1YWxzIGhhdmUgYSBmYWlybHkgbm9ybWFsIGRpc3RpcmJ1dGlvbiB3aXRoIHRoZSBleGNlcHRpb24gb2Ygc29tZSBwb3NpdHZlIHNrZXduZXNzLgoKKipIZXRlcm9za2FkaXNjaXR5Kio6IEFsdGhvdWdoIHRoZSByZXNpZHVhbHMgYXJlIHN0aWxsIG5vdCBoZXRlcm9za2FkaXN0aWMsIHRoZXJlIGhhcyBiZWVuIHNvbWUgaW1wcm92ZW1lbnQuIAoKKipPdXRsaWVyczoqKiBUaGVyZSBpcyBvbmUgb2JzZXJ2YXRpb24gd2l0aCBoaWdoIGxldmVyYWdlIGJ1dCBub3QgaGlnaCBpbmZsdWVuY2UuCgpOZXh0IFN0ZXBzOiBIZXRlcm9za2FkaXNjaXR5IGNvdWxkIGJlIGEgc2lnbiBvZiBvbWl0dGVkIHZhcmlhYmxlcy4KCmBgYHtyfQptMiA8LSBsbShsb2coY3JtcnRlKSB+IGxvZyhlZmZfY2opLCBkYXRhID0gZGF0YTIpOwpgYGAKCg==